#!/usr/bin/env python
"""
$Id$
"""

import sys
import code
from random import randint, choice
from optparse import OptionParser
from sqlobject import connectionForURI
from modelo.projeto import Projeto
from modelo.amostra import Amostra
from modelo.tipo_amostra import TipoAmostra
from modelo.cientista import Cientista
from modelo.local import Local
from modelo.container import Container
from modelo.laboratorio import Laboratorio

from modelo.projeto import ProjetoLocal
from modelo.projeto import ProjetoCientista
from modelo.projeto import ProjetoTipoAmostra

from modelo.unidade.concentracao import Concentracao
from modelo.unidade.peso import Peso
from modelo.unidade.volume import Volume

connection = None
order = ('concentracao peso volume '
         'local container projeto '
         'tipoamostra amostra '
         'laboratorio cientista '
         'projeto_local projeto_cientista projeto_tipo_amostra').split()

def main(order=order, stream=sys.stdout):
    global connection

    cleanup()
    for tname in order:
        klass = table_map[tname]
        klass.createTable(ifNotExists=1)
    populate()
    local = locals()
    local.update(globals())
    code.interact(local=local)

def interact():
    local = locals()
    local.update(globals())
    code.interact(local=local)
    return True

def initialize(connection):
    global order, table_map
    table_map = {'projeto':Projeto,
                 'amostra':Amostra,
                 'tipoamostra':TipoAmostra,
                 'container':Container,
                 'local':Local,
                 'cientista':Cientista,
                 'laboratorio':Laboratorio,
                 'concentracao':Concentracao,
                 'volume':Volume,
                 'peso':Peso,
                 'projeto_local':ProjetoLocal,
                 'projeto_cientista':ProjetoCientista,
                 'projeto_tipo_amostra':ProjetoTipoAmostra,
                 }
    for kname in order:
        for k, v in table_map.items():
            v._connection = connection
            if v.__name__ == kname:
                order.append(k)

def reset():
    t = [table_map.get(o) for o in order]
    t.reverse()
    [o.clearTable() for o in t]

def cleanup():
    t = [table_map.get(o) for o in order]
    t.reverse()
    [o.dropTable() for o in t]

def populate():
    for i in range(0, 10):
        labs = [Laboratorio(nome='Laboratorio %s.%s' % (i, j))
                for j in range(1, 4)]
        p = Projeto(nome='Projeto %s' % i)
        for j in range(1, 5):
            l = choice(labs)
            c = Cientista(nome='Cientista %s.%s' % (i, j), laboratorio_id=l.id)
            pc = ProjetoCientista(projeto_id=p.id, cientista_id=c.id)
        ta = TipoAmostra(nome='Tipo Amostra %s' % i)
        pta = ProjetoTipoAmostra(projeto_id=p.id, tipo_amostra_id=ta.id)
        lo = Local(nome='Local %s.%s' % (i, j))
        pl = ProjetoLocal(projeto_id=p.id, local_id=lo.id)
        for j in range(1, 4):
            ct = Container(nome='Container %s.%s' % (i, j),
                           local_id=randint(1, i+1))
        co = Concentracao(nome='Concentracao %s' % i, expoente=10 ** randint(-3, 3))
        vo = Volume(nome='Volume %s' % i, expoente=10 ** randint(-3, 3))
        pe = Peso(nome='Peso %s' % i, expoente=10 ** randint(-3, 3))
        for j in range(1, 2):
            u = (('volume_id', randint(1, i+1)),
                 ('peso_id', randint(1, i+1)),
                 ('concentracao_id', randint(1, i+1)),
                 )
            n, v = choice(u)
            d = {'tipo_amostra_id':ta.id,
                 'container_id':ct.id,
                 'nome':'Amostra %s.%s' % (i, j),
                 n:v,
                 n[:-3]:randint(0, 10)}
            a = Amostra(**d)

def consume(options, args):
    global connection, db_type, order
    from pprint import pprint

    dsn = getattr(options, 'dsn') or 'postgres://sidnei:123@localhost/bd1'
    debug = bool(getattr(options, 'debug') or True)

    print 'Accessing with:'
    pprint({'dsn':dsn,
            })

    connection = connectionForURI(dsn)
    connection.debug = debug

    initialize(connection)

    if args:
        order = filter(lambda x: x in args, order)

    if getattr(options, 'interact', None) is not None:
        return interact()

    return main(order)

if __name__ == '__main__':
    parser = OptionParser()
    parser.add_option('-i', '--interact',
                      action='store_const',
                      const=True,
                      dest='interact',
                      help='Enter Interactive Mode')
    parser.add_option('-d', '--dsn',
                      dest='dsn',
                      help='DSN')
    parser.add_option('-D', '--debug',
                      action='store_const',
                      const=True,
                      dest='debug',
                      help='Debug queries')
    (options, args) = parser.parse_args()
    consume(options, args)
